﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;

namespace MuYue.Http
{
    /// <summary>
    /// HTTP协议头
    /// </summary>
    internal class HttpHeader
    {
        #region 常用属性
        /// <summary>
        /// 正文的编码方式
        /// </summary>
        public Encoding ContentEncoding { set; get; }
        /// <summary>
        /// 正文的长度
        /// </summary>
        public long ContentLength { set; get; }
        /// <summary>
        /// 接收字长是按什么来算的
        /// </summary>
        public bool Chuncked { set; get; }
        /// <summary>
        /// HTTP协议版本
        /// </summary>
        public string Protocol { get; set; }
        /// <summary>
        /// 状态码
        /// </summary>
        public HttpStatusCode Status { get; set; }
        /// <summary>
        /// 重定向的网址
        /// </summary>
        public string ReferUrl { get; set; }
        #endregion

        /// <summary>
        /// 网站的COOKIE
        /// </summary>
        internal List<string> Cookies { set; get; }

        /// <summary>
        /// 除了COOKIE之外的所有头
        /// </summary>
        internal Dictionary<string, string> Headers {
            private set;
            get;
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        internal HttpHeader() {
            this.Headers = new Dictionary<string, string>();
            this.Cookies = new List<string>();
        }

        /// <summary>
        /// 解析第一行信息
        /// </summary>
        /// <param name="str"></param>
        public void AnalyFirstLine(string str) {
            var strArray = str.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);
            if (strArray.Length > 2) {
                SetProtocol(strArray[0]);
                SetStatus(strArray[1]);
            }
        }

        /// <summary>
        /// 添加头元素
        /// </summary>
        /// <param name="fullHeader"></param>
        internal void Add(string fullHeader) {
            var index = fullHeader.IndexOf(":");
            if (index < 0)
                return;
            var key = fullHeader.Substring(0, index).Trim();
            var val = fullHeader.Substring(index + 1).Trim();
            if (key.Equals("Set-Cookie", StringComparison.OrdinalIgnoreCase)) {
                SetCookies(val);
            }
            else if (key.Equals("Content-Length", StringComparison.OrdinalIgnoreCase)) {
                index = fullHeader.IndexOf(":");
                long contentLength = 0;
                if (index > 0)
                    long.TryParse(fullHeader.Substring(index + 1).Trim(), out contentLength);
                this.ContentLength = contentLength;
                Headers.Add("Content-Length", contentLength.ToString());
            }
            else if (key.Equals("Content-Type", StringComparison.OrdinalIgnoreCase)) {
                index = val.IndexOf(";");
                if (index > 0) {
                    Headers.Add(key, val.Substring(0, index));
                    var str = val.Substring(index + 1);
                    index = str.IndexOf("=");
                    if (index > 0) {
                        var encodingstring = str.Substring(index + 1).Trim();
                        encodingstring = (encodingstring == "utf8") ? "utf-8" : encodingstring;
                        this.ContentEncoding = Encoding.GetEncoding(encodingstring);
                        Headers.Add("Encoding", encodingstring);
                    }
                }
            }
            else if (key.Equals("Transfer-Encoding", StringComparison.OrdinalIgnoreCase)) {
                this.Chuncked = val.Equals("chunked", StringComparison.OrdinalIgnoreCase);
                Headers.Add(key, val);
            }
            else if (key.Equals("Location", StringComparison.OrdinalIgnoreCase)) {
                Headers.Add(key, val);
                this.ReferUrl = val;
            }
            else if (!Headers.Keys.Contains(key)) {
                Headers.Add(key, val);
            }
        }

        /// <summary>
        /// 设置COOKIE
        /// </summary>
        /// <param name="cookies"></param>
        private void SetCookies(string cookies) {
            Cookies.Add(cookies);
        }

        /// <summary>
        /// 设置协议版本
        /// </summary>
        /// <param name="protocol"></param>
        private void SetProtocol(string protocol) {
            this.Protocol = protocol;
        }

        /// <summary>
        /// 设置状态吗
        /// </summary>
        /// <param name="status"></param>
        /// <param name="statusDescription"></param>
        private void SetStatus(string status) {
            var statusNum = 0;
            Int32.TryParse(status, out statusNum);
            this.Status = (HttpStatusCode)statusNum;
        }
    }
}
